<?php

require_once(PATH_TO_APP . "/components/printcomposer/PaperSize.php");

class PrintComposer
{
    private $map_;
    private $arr_paper_sizes_ = array();
    private $arr_positions_ = array();
    private $legend_position_ = -1;
    
    const MAP_RESOLUTION = 72;
    
    const MAP_MAX_RESOLUTION = 400;
    
    //1 inch = 25.4 mm
    const SIZE_RATIO = 25.4;
    
    const ORIENTATION_LANDSCAPE = 'landscape';
    
    const ORIENTATION_PORTRAIT = 'portrait';
    
    public function __construct(&$map)
    {
        $this->map_ = $map;
        $this->arr_positions_[MS_LR] = 0;
        $this->arr_positions_[MS_LC] = 0;
        $this->arr_positions_[MS_LL] = 0;
        $this->readPaperSizes();
    }
    
    public function __destruct(){}
    
    public function getPaperSizes($format_string)
    {
        $arr_return = array();
        foreach($this->arr_paper_sizes_ as $key => $value)
        {
            $arr_return[$key] = $this->createOuputFormatString($format_string, $value);
        }
        return $arr_return;
    }
    
    public function createExport($format_id, $table_details, $request)
    {
        if(!array_key_exists($format_id, $this->arr_paper_sizes_))
            $format = reset($this->arr_paper_sizes_);
        else
            $format = $this->arr_paper_sizes_[$format_id];
        $resolution = (int)$request->getParameter('post', 'image_quality') > 0 && (int)$request->getParameter('post', 'image_quality') <= constant("self::MAP_MAX_RESOLUTION") ? (int)$request->getParameter('post', 'image_quality') : constant("self::MAP_RESOLUTION");
        $this->map_->set('resolution', $resolution);
        if($request->getParameter('post', 'paper_orientation') == constant("self::ORIENTATION_PORTRAIT"))
        {
            $map_width = floor($format->getHeight() / constant("self::SIZE_RATIO") * $resolution);
            $map_height = floor($format->getWidth() / constant("self::SIZE_RATIO") * $resolution);
        }
        else
        {
            $map_width = floor($format->getWidth() / constant("self::SIZE_RATIO") * $resolution);
            $map_height = floor($format->getHeight() / constant("self::SIZE_RATIO") * $resolution);
        }
        $this->addNorthArrow($resolution, $map_width);
        $this->addHeading($map_height, $table_details);
        $this->addCopyright($map_width, $request);
        $this->map_->setSize($map_width, $map_height);
        $this->scaleScalebar($resolution);
        $this->scaleLegend($resolution);
    }
    
    public function addLegendAndScalebarPosition($legend_position, $scalebar_position)
    {
        $this->arr_positions_[$legend_position] = 1;
        $this->arr_positions_[$scalebar_position] = 1;
        $this->legend_position_ = $legend_position;
    }
    
    private function addNorthArrow($resolution, $width)
    {
        $northarrow = $this->map_->getLayerByName('northarrow');
        $northarrow->set('status', MS_ON);
        $shape = ms_newShapeObj(MS_SHAPE_POINT);
        $pt = ms_newLineObj();
        //xratio: -0.416
        $x = round(-0.416*$resolution);
        if($this->legend_position_ == MS_LR)
        {
            $x = ($width + $x)*-1;
        }
        $pt->addXY($x, $resolution*-1);
        $shape->add($pt);
        $northarrow->addFeature($shape);
    }
    
    private function calculateFontSize($resolution, $ratio)
    {
        $font_size = round($ratio*$resolution);
        if($font_size < 7)
        {
            $font_size = 7;
        }
        elseif($font_size > 40)
        {
            $font_size = 40;
        }
        return $font_size;
    }
    
    private function scaleScalebar($resolution)
    {
        $font_size = $this->calculateFontSize($resolution, 0.125);
        $this->map_->scalebar->set('width', round(2*$resolution));
        $this->map_->scalebar->set('height', round(0.1*$resolution));
        $this->map_->scalebar->label->set('size', $font_size);
    }
    
    private function scaleLegend($resolution)
    {
        $font_size = $this->calculateFontSize($resolution, 0.1527);
        $keysizex = round($font_size / 0.611);
        $this->map_->legend->label->set('size', $font_size);
        $this->map_->legend->set('keysizex', $keysizex);
        $this->map_->legend->set('keysizey', round($keysizex/1.2));
        $this->map_->legend->set('keyspacingx', round($keysizex/3.6));
        $this->map_->legend->set('keyspacingy', round($keysizex/3.6));
    }
    
    private function readPaperSizes()
    {   
        $filename = PATH_TO_APP . "/components/printcomposer/paper_size.xml";
        $xml = @simplexml_load_file($filename);
        if(!$xml)
            return false;
        foreach($xml as $key => $value)
        {
            $this->arr_paper_sizes_[(string)$value->name] = new PaperSize((string)$value->name, (int)$value->width, (int)$value->height);
        }
        return true;
    }
    
    private function createOuputFormatString($format_string, PaperSize $paper_size)
    {
        $format_string = str_replace(':name', $paper_size->getName(), $format_string);
        $format_string = str_replace(':width', $paper_size->getWidth(), $format_string);
        $format_string = str_replace(':height', $paper_size->getHeight(), $format_string);
        return $format_string;
    }
    
    private function addHeading($height, $table_details)
    {
        $heading = $this->map_->getLayerByName('heading');
        $heading->set('status', MS_ON);
        $shp = ms_newShapeObj(MS_SHAPE_POINT);
        $pt = ms_newLineObj();
        $pt->addXY(30,30);
        $shp->add($pt);
        $shp->set('text', $table_details->dt_titel . " (" . $table_details->g_name . " - " . $table_details->e_name . ")");
        $heading->addFeature($shp);
    }
    
    private function addCopyright($width, $request)
    {
        $copyright = $this->map_->getLayerByName('copyright');
        $copyright->set('status', MS_ON);
        $shp = ms_newShapeObj(MS_SHAPE_POINT);
        $pt = ms_newLineObj();
        $pos = -1;
        foreach($this->arr_positions_ as $key => $value)
        {
            if($value == 0)
            {
                $pos = $key;
                break;
            }
        }
        switch($pos)
        {
            case MS_LR:
                $pt->addXY($width-10,0);
                break;
            case MS_LC:
                $pt->addXY(ceil($width/2),0);
                break;
            default:
                $pt->addXY(10,0);
        }
        $shp->add($pt);
        $shp->set('text', strip_tags($request->getParameter('post', 'copyright')));
        $copyright->addFeature($shp);
    }

}

?>
